// xkImgBit8.cpp: implementation of the xkImgBit8 class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "xkImgBit8.h"

#include "xkImgCheck.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#define GetGray(r,g,b) ((int)r+(int)g+(int)b)/3 


xkImgBit* CreateImgBit8()
{
	xkImgBit8* pPlug = new xkImgBit8;
	
	if(NULL != pPlug)
	{
		return (xkImgBit*)pPlug;
	}
	
	return (NULL);
}


xkImgBit8::xkImgBit8()
{
    m_hWnd = NULL;

	m_pOrgImage = NULL;
	m_pImage = NULL;

	for(int i=0;i<MAX_UNDO_LEVELS;i++)
	{
		m_pImageUndo[i] = NULL;
	}
	m_nUndoLevel = 0;
      
	m_dwLastProMode = ImagePro_Unknown;

	m_sDstSize.cx = 768;
	m_sDstSize.cy = 576;
}

xkImgBit8::~xkImgBit8()
{
    UnInitialize();	
}

void xkImgBit8::UnInitialize()
{
	MySafeDelete(m_pOrgImage);
	MySafeDelete(m_pImage);
	for(int i=0;i<MAX_UNDO_LEVELS;i++)
	{
		MySafeDelete(m_pImageUndo[i]);
	}
	m_nUndoLevel = 0;
}  

int xkImgBit8::Initialize()
{
	UnInitialize(); 

	return 0;
}


int xkImgBit8::SetImgBit(zkImgBitInfo *pImgInfo)
{
	m_pImgInfo = pImgInfo;

	return 0;
}

int xkImgBit8::LoadFile(char *pFileName)
{
	UnInitialize();

	xkImgCheck xCheck;
    DWORD dwType = 0;
	if( xCheck.CheckFileType( pFileName,dwType ) < 0 )
	{
		return -1;
	}

	m_pImage = new CxImage((const char*)pFileName, dwType);

	if( !m_pImage->IsValid() )
	{
		MySafeDelete(m_pImage);
		return -1;
	}

	m_pOrgImage = new CxImage();
	m_pOrgImage->Copy( *m_pImage );

	m_dwLastProMode = ImagePro_Unknown;

	m_sDstSize.cx = m_pImage->GetWidth();
	m_sDstSize.cy = m_pImage->GetHeight();

	return 0;
}


int xkImgBit8::GetColorTableEntries( int nBitCount )
{
	int nColorTableEntries = 256;
	switch(nBitCount)
	{
		case 1:
			nColorTableEntries = 2;
			break;
		case 4:
			nColorTableEntries = 16;
			break;
		case 8:
			nColorTableEntries = 256;
			break;
		case 10:
			nColorTableEntries = 1024;
			break;
		case 12:
			nColorTableEntries = 4096;
			break;
		case 16:
		case 24:
		case 32:
			nColorTableEntries = 0;
			break;
		default:
			break;
	}
	
	return nColorTableEntries;
}

int xkImgBit8::SetImgBuffer(zkImgBitInfo *pImgInfo,BOOL bShareMem)
{
	int nRet = DD_ERR_FAILURE;

	UnInitialize();

// 	if( NULL == pBitInfo )
// 	{
// 		return DD_ERR_FAILURE;
// 	}
// 
// 	//int nHeaderSize = sizeof(BITMAPINFOHEADER);
// 	//nHeaderSize += sizeof(RGBQUAD) * GetColorTableEntries( pBitInfo->biBitCount );
// 	int nHeaderSize = sizeof(BITMAPINFOHEADER) + pBitInfo->biClrUsed * sizeof(RGBQUAD);
// 
// 	int nDataLen = pBitInfo->biHeight * pBitInfo->biWidth * (pBitInfo->biBitCount>>3);
// 
// 
// 	int type = CXIMAGE_FORMAT_BMP;
// 	int nSize = nHeaderSize + nDataLen;
// 	m_pImage = new CxImage( (BYTE*)pBitInfo,nSize,type);
// 
// 	if( !m_pImage->IsValid() )
// 	{
// 		MySafeDelete(m_pImage);
// 		return DD_ERR_FAILURE;
// 	}
// 
//     m_pOrgImage = new CxImage();
// 	m_pOrgImage->Copy( *m_pImage );
//      
// 	m_dwLastProMode = ImagePro_Unknown;
// 
// 	m_sDstSize.cx = m_pImage->GetWidth();
// 	m_sDstSize.cy = m_pImage->GetHeight();

	return nRet;
}

int xkImgBit8::GetImgBuffer(zkImgBitInfo **ppImgInfo)
{
	if( NULL == m_pImage || !m_pImage->IsValid() || NULL == m_pImgInfo )
	{
		return DD_ERR_FAILURE;
	}

	BYTE *pBuffer = (BYTE*)m_pImage->GetDIB();
	void *pData   = (void*)( pBuffer + sizeof(BITMAPINFOHEADER) + m_pImage->GetPaletteSize() );

	int nBpp = m_pImage->GetBpp();

	m_pImgInfo->nImgDefine    = eImage_Define_Img8;
	if( nBpp > 8) 
	{
		m_pImgInfo->nBitPerSample = 8;
		m_pImgInfo->nSapPerPixel  = nBpp/8;
	}
	else
	{
		m_pImgInfo->nBitPerSample = nBpp;
		m_pImgInfo->nSapPerPixel  = 1;
	}
	m_pImgInfo->nWidth        = m_pImage->GetWidth();
	m_pImgInfo->nHeight       = m_pImage->GetHeight();
	m_pImgInfo->bAutoDelete   = FALSE;
	m_pImgInfo->pImageData    = pData;

	*ppImgInfo = m_pImgInfo;

	return DD_ERR_SUCCESS;
}

int xkImgBit8::Restore()
{
	return 0;
}

int xkImgBit8::Operate(DWORD dwProMode,void *pVoid)
{
	int nRet = DD_ERR_FAILURE;
	
	if( NULL == m_pImage || !m_pImage->IsValid() )
	{
		return nRet;
	}
	
	BOOL bSubUndo = TRUE;

	
	if( ImagePro_Emboss == m_dwLastProMode && ImagePro_Emboss == dwProMode )
	{
        bSubUndo = FALSE;
	}
	
	if( bSubUndo )
	{
		SubmitUndo();
	}

	nRet = DD_ERR_SUCCESS;
		
	switch (dwProMode)
	{
	case ImagePro_Restore:
		{
			Restore();
		}
		break;
	case ImagePro_GradsSharp:
		{
			nRet = DD_ERR_SUCCESS;
			m_pImage->Edge();
		}
		break;
	case ImagePro_EdgeSharp:
		{
			nRet = DD_ERR_SUCCESS;
			long kernel[]={-1,-1,-1,-1,8,-1,-1,-1,-1};
			m_pImage->Filter(kernel,3,-1,255);
		}
		break;
	case ImagePro_Sharp:
		{
			nRet = DD_ERR_SUCCESS;
			long kernel[]={-1,-1,-1,-1,16,-1,-1,-1,-1};
			m_pImage->Filter(kernel,3,8,0);
		}
		break;
	case ImagePro_Smooth:
		{
			nRet = DD_ERR_SUCCESS;
			long kernel[]={1,1,1,1,8,1,1,1,1};
			m_pImage->Filter(kernel,3,16,0);
		}
		break;
	case ImagePro_Emboss:
		{
			if( NULL != pVoid )
			{
				CxImage *pImage = m_pImageUndo[m_nUndoLevel-1];
				if( NULL == pImage || !pImage->IsValid() )
				{
					pImage = m_pOrgImage;
				}
				m_pImage->Copy( *pImage );
				
				nRet = DD_ERR_SUCCESS;
				int *pnData = (int*)(pVoid);
				long kernel[]={0,0,-1,0,0,0,1,0,0};
				m_pImage->Filter(kernel,3,0,*pnData);
			}	
		}
		break;
	case ImagePro_Rotate:
		{
			nRet = DD_ERR_SUCCESS;
			float *pfData = (float*)(pVoid);
            long *pnData = (long*)(pVoid);
			m_pImage->Rotate2( *pfData );
		}
		break;
	
	case ImagePro_HighStrain:
		{
			nRet = DD_ERR_SUCCESS;
			long kernel[]={-1,-1,-1,-1,15,-1,-1,-1,-1};
		    m_pImage->Filter(kernel,3,7,0);
		}
		break;
	case ImagePro_LowStrain:
		{
			nRet = DD_ERR_SUCCESS;
			long kernel[]={1,1,1,1,1,1,1,1,1};
			m_pImage->Filter(kernel,3,9,0);
		}
		break;
	case ImagePro_MedianStrain:
		{
			nRet = DD_ERR_SUCCESS;
			int *pnData = (int*)(pVoid);
			m_pImage->Median( *pnData );
		}
		break;
	case ImagePro_ProXiaoBo:
		{
			nRet = DD_ERR_SUCCESS;
			m_pImage->Contour();
		}
		break;
	case ImagePro_Compose:
		{
		}
		break;
	default:
		{
		}
		break;
	}

	m_dwLastProMode = dwProMode;
	
	return nRet;
}

int xkImgBit8::GetImageSize(int &nWidth,int &nHeight)
{
	if( NULL == m_pImage       ||
		!m_pImage->IsValid() )
	{
		return DD_ERR_FAILURE;
	}

	nWidth = m_pImage->GetWidth();
	nHeight = m_pImage->GetHeight();

	return DD_ERR_SUCCESS;
}

void xkImgBit8::SubmitUndo()
{
	if( m_nUndoLevel >= MAX_UNDO_LEVELS )   // Max Undo reached
	{	
		MySafeDelete(m_pImageUndo[0]);		// discard the early undo
		for(int i=1;i<MAX_UNDO_LEVELS;i++)
		{
			m_pImageUndo[i-1] = m_pImageUndo[i]; //shift the history
		}
		m_pImageUndo[MAX_UNDO_LEVELS-1] = NULL;	// clear the undo slot
		m_nUndoLevel = MAX_UNDO_LEVELS - 1;     // reposition at last level
	}
	// we must clear the "redo" history when a new action is performed
	for (int i=m_nUndoLevel;i<MAX_UNDO_LEVELS;i++)
	{
		MySafeDelete(m_pImageUndo[i]);
	}
	// save the actual image in the undo history
	if( m_pImage->IsValid() )
	{
		m_pImageUndo[m_nUndoLevel] = new CxImage();
		m_pImageUndo[m_nUndoLevel]->Copy( *m_pImage );
		m_nUndoLevel++;
	}
}


int xkImgBit8::Undo(int nStep)
{
	if( -1 == nStep )
	{
        m_nUndoLevel = 0;
		m_pImage->Copy(*m_pOrgImage);
		return 0;
	}

	m_nUndoLevel--;

	if( m_nUndoLevel < 0 )
	{
		m_nUndoLevel = 0;
		return DD_ERR_FAILURE;
	}

	if( NULL == m_pImageUndo[m_nUndoLevel] )
	{
		return -1;
	}

	m_dwLastProMode = ImagePro_Unknown;

	CxImage* tmp = m_pImage;
	m_pImage = m_pImageUndo[m_nUndoLevel];
	m_pImageUndo[m_nUndoLevel] = tmp;

	return DD_ERR_SUCCESS;
}

int xkImgBit8::Redo()
{
	if( m_nUndoLevel >= MAX_UNDO_LEVELS )
	{
		m_nUndoLevel = MAX_UNDO_LEVELS - 1;
		return DD_ERR_FAILURE;
	}

	if( NULL == m_pImageUndo[m_nUndoLevel] )
	{
		return -1;
	}

	CxImage* tmp = m_pImage;
	m_pImage = m_pImageUndo[m_nUndoLevel];
	m_pImageUndo[m_nUndoLevel] = tmp;
	m_nUndoLevel++;

	return DD_ERR_SUCCESS;
}
 
int	xkImgBit8::Draw(void *pVoid)
{
	if( NULL == m_pImage )
	{
		return DD_ERR_FAILURE;
	}  
	
	return DD_ERR_SUCCESS;
}

int xkImgBit8::GetGrayValue(int x,int y,DWORD &dwGray)
{
	if( NULL == m_pImage || !m_pImage->IsValid() )
	{
		dwGray = 0;
		return DD_ERR_FAILURE;
	}

	//int nY = m_pImage->GetHeight() - y -1;
	RGBQUAD xRGB = m_pImage->GetPixelColor(x,y);
    dwGray = GetGray(xRGB.rgbRed,xRGB.rgbGreen,xRGB.rgbBlue);;

	return DD_ERR_SUCCESS;
}

int xkImgBit8::GetLineGray(POINT tStart,POINT tEnd,zkImgLineGray **ppLineGray)
{
	if( NULL == m_pImage || !m_pImage->IsValid() )
	{
		*ppLineGray = 0;
		return DD_ERR_FAILURE;
	}

	return 0;
}

int xkImgBit8::GetGrayLevels(int &nGrayLevels)
{
	nGrayLevels = 256;

	return DD_ERR_SUCCESS;
}

int xkImgBit8::GetHistogramInfo(zkImgHistogram **ppHistogram)
{
	if( NULL == m_pImage || !m_pImage->IsValid() )
	{
		return DD_ERR_FAILURE;
	}
	
	int nGrayLevels = GetColorTableEntries( 8 );//m_pImage->GetBpp() );

	DWORD *pdwPixels = m_xImgHistogram.pdwPixels;

	if( m_xImgHistogram.dwBufSize != nGrayLevels )
	{
		MySafeDeleteMAB(m_xImgHistogram.pdwPixels);

		m_xImgHistogram.dwBufSize = nGrayLevels;
		pdwPixels = new DWORD[ nGrayLevels + 10];
		m_xImgHistogram.pdwPixels = pdwPixels;
	}

	memset( pdwPixels,0,nGrayLevels*sizeof(DWORD) );

	int nH = m_pImage->GetHeight();
	int nW = m_pImage->GetWidth();
	int nGrayLevel = 0;
	DWORD dwMaxPixel = 0;

	BYTE *pBuffer = (BYTE*)m_pImage->GetDIB();
	void *pData   = (void*)( pBuffer + sizeof(BITMAPINFOHEADER) + m_pImage->GetPaletteSize() );

	int nPixelSize = ( (BITMAPINFOHEADER*)pBuffer )->biBitCount;
	if( nPixelSize == 8 )
	{
		int nSize = nH * nW;
		for(int i=0;i<nSize;i++)
		{
			nGrayLevel = *( (BYTE*)pData + i );

			pdwPixels[nGrayLevel] += 1;

			//dwMaxPixel = max( dwMaxPixel,pdwPixels[nGrayLevel] );
		}
	}
	else if( nPixelSize >= 24 )
	{
		//RGBQUAD xRGB;
		for(int i=0;i<nH;i++)
		{
			for(int j=0;j<nW;j++)
			{
				nGrayLevel = m_pImage->GetPixelGray(i,j);
				//xRGB = m_pImage->GetPixelColor(j,i);
				//nGrayLevel = GetGray(xRGB.rgbRed,xRGB.rgbGreen,xRGB.rgbBlue);;

				pdwPixels[nGrayLevel] += 1;

				//dwMaxPixel = max( dwMaxPixel,pdwPixels[nGrayLevel] );
			}
		}
	}

	m_xImgHistogram.nLineHistogram    = 0;
	m_xImgHistogram.nBpp              = 8;
	m_xImgHistogram.nDark             = 0;
	m_xImgHistogram.nBright           = 255;
	m_xImgHistogram.dwMaxPixel        = nH * nW / nGrayLevels * 2;
	m_xImgHistogram.dwStatisticsCount = nH * nW ;
	m_xImgHistogram.dwBufSize         = nGrayLevels;

	*ppHistogram = &m_xImgHistogram;

	return DD_ERR_SUCCESS;
}

int xkImgBit8::SaveFile(char* pFileName)
{
	if( NULL == m_pOrgImage || NULL == m_pImage)
	{
		return DD_ERR_FAILURE;
	}
  
	BOOL bRet = FALSE;

	const char* ext = FindExtension(pFileName);
	if( strlen(ext) <= 0 ) 
	{
		return DD_ERR_FAILURE;
	}

	int nType = FindType(ext);

	bRet = m_pOrgImage->Save( (TCHAR*)pFileName,nType );
	
	
// 	}
// 	else
// 	{
// 		if( !m_pImage->IsValid() )
// 		{
// 			return DD_ERR_FAILURE;
// 		}

// 		CString strMarkFile = (CString)bstrFileName;
// 		
// 		int nFind = strMarkFile.ReverseFind( '.' );
// 		if( nFind > 0 )
// 		{
// 			strMarkFile = strMarkFile.Left(nFind);
// 		}
// 		strMarkFile += ImgMarkFileExtName;
// 
// 		CString filename = strMarkFile;
// 		CString ext( FindExtension(filename) );
// 		ext.MakeLower();
// 		if (ext == "") 
// 		{
// 			return 0;
// 		}  
// 		
// 		int nType = FindType(ext);
// 		
// 		TCHAR *pMarkFile = strMarkFile.GetBuffer(0);
//  
// 		bRet = m_pImage->Save( pMarkFile,nType ); 
//   
// 		strMarkFile.ReleaseBuffer();

	 
	return bRet?0:-1;
}

const char* xkImgBit8::FindExtension(const char* name)
{
	int len = strlen(name);
	int i;
	for (i = len-1; i >= 0; i--)
	{
		if (name[i] == '.')
		{
			return &name[i+1];
		}
	}
	return "";
}

int xkImgBit8::FindType(const char* ext)
{
	int type = 0;
	if( strcmp( ext,"bmp") == 0 )					type = CXIMAGE_FORMAT_BMP;
#if CXIMAGE_SUPPORT_JPG
	else if ( strcmp(ext,"jpg") == 0 || strcmp(ext,"jpeg") == 0 )
	{
		type = CXIMAGE_FORMAT_JPG;
	}
#endif

#if CXIMAGE_SUPPORT_TIF
	else if ( strcmp(ext,"tiff") == 0|| strcmp(ext,"tif") == 0 )
	{
		type = CXIMAGE_FORMAT_TIF;
	}
#endif
	else type = CXIMAGE_FORMAT_UNKNOWN;

	return type;
}



int xkImgBit8::GetImageAreaPoint(RECT *pAreaRect,zkImgAreaPoint *pImgArea)
{
	CxImage *pAreaImage = new CxImage;
	m_pImage->Crop(*pAreaRect,pAreaImage);

    pImgArea->nImgDefine = eImage_Define_Img8;
	pImgArea->pVoid = (void*)pAreaImage;
	
	return DD_ERR_SUCCESS;
}
 
int xkImgBit8::SetAreaPoint(void *pVoid)
{
	UnInitialize();

	zkImgAreaPoint *pPoint = (zkImgAreaPoint*)pVoid;

	m_pImage = (CxImage*)( pPoint->pVoid );

	if( !m_pImage->IsValid() )
	{
		MySafeDelete(m_pImage);
		return DD_ERR_FAILURE;
	}

    m_pOrgImage = new CxImage();
	m_pOrgImage->Copy( *m_pImage );
     
	m_dwLastProMode = ImagePro_Unknown;

	m_sDstSize.cx = m_pImage->GetWidth();
	m_sDstSize.cy = m_pImage->GetHeight();

	return DD_ERR_SUCCESS;
}







void xkImgBit8::CalGrayLevels(CxImage *pImage,int nLow,int nHigh)
{
	int nH = pImage->GetHeight();
	int nW = pImage->GetWidth();
	int nGrayLevel = 0;
	DWORD dwMaxPixel = 0;
	RGBQUAD xRGB;

	float fRate = 255;
	if( nHigh == nLow )
	{
		fRate = 1;
	}
	else
	{
		fRate /= (nHigh - nLow);
	}

	for(int i=0;i<nH;i++)
	{
		for(int j=0;j<nW;j++)
		{
			//nGrayLevel = m_pImage->GetPixelGray(i,j);
            xRGB = pImage->GetPixelColor(j,i);
            nGrayLevel = GetGray(xRGB.rgbRed,xRGB.rgbGreen,xRGB.rgbBlue);;
 
			if( nGrayLevel <= nLow )
			{
				memset(&xRGB,0,sizeof(RGBQUAD));
				pImage->SetPixelColor(j,i,xRGB);
			}
			else if( nGrayLevel >= nHigh )
			{
				memset(&xRGB,255,sizeof(RGBQUAD));
				pImage->SetPixelColor(j,i,xRGB);
			}
			else
			{
				nGrayLevel -= nLow;
                nGrayLevel = (int)(fRate*nGrayLevel);
				memset(&xRGB,nGrayLevel,sizeof(RGBQUAD));
				pImage->SetPixelColor(j,i,xRGB);
			}
		}
	}

}
 

#define GetXORValue(x) if(x<70||x>180){x=x^255;}else{x=255;} 

int xkImgBit8::MarkConposite(BYTE *pBuffer,DWORD dwPitch,DWORD dwWidth,DWORD dwHeight,DWORD dwPixelSize,int nImage)
{
	CxImage *pImage = NULL;
	if( 0 == nImage )
	{
		pImage = m_pOrgImage;
	}
	else if( 1 == nImage )
	{
		pImage = m_pImage;
	}
	else
	{
		return 0;
	}

	if( NULL == pBuffer|| NULL == pImage || !pImage->IsValid() )
	{
		return DD_ERR_FAILURE;
	}

	if( pImage->GetHeight() != dwHeight || pImage->GetWidth() != dwWidth )
	{
		return DD_ERR_FAILURE;
	}

	int nHeight = pImage->GetHeight();

	RGBQUAD xRGB;
	DWORD   dwOffset = 0;
	
	for(DWORD i=0;i<dwHeight;i++)
	{
		dwOffset = i * dwPitch;

		for(DWORD j=0;j<dwWidth;j++)
		{
			if( *( (DWORD*)(pBuffer+dwOffset+j*dwPixelSize) ) > 10 )
			{
				xRGB = pImage->GetPixelColor(j,i);

				GetXORValue(xRGB.rgbRed); 
				GetXORValue(xRGB.rgbGreen); 
				GetXORValue(xRGB.rgbBlue);

				pImage->SetPixelColor(j,i,xRGB);
			}	
		}
	}

	if( 0 == nImage )
	{
		m_pImage->Copy( *m_pOrgImage );
	}

	return DD_ERR_SUCCESS;
}



int xkImgBit8::ImageConposite(int nX,int nY,BOOL bSetOrgImage)
{
// 	BITMAP stBitMap;
// 	m_pGraph->GetBitmap( &stBitMap );
// 	
// 	
// 	int nBufSize = stBitMap.bmWidth * stBitMap.bmHeight * (stBitMap.bmBitsPixel >> 3);
// 	BYTE *pSrcBuffer = new BYTE[nBufSize+100];
// 	
// 	m_pGraph->GetBitmapBits(nBufSize,(LPVOID)pSrcBuffer);
// 
// 	switch( stBitMap.bmBitsPixel )
// 	{
// 	case 8:
// 		{
// 			int nHeight = m_pImage->GetHeight();
// 
// 			RGBQUAD xRGB;
// 			int nOffset = 0;
// 			for(int i=0;i<stBitMap.bmHeight;i++)
// 			{
// 				for(int j=0;j<stBitMap.bmWidth;j++)
// 				{
// 					nOffset = (i*stBitMap.bmWidth +j);
// 
// 					if( *(pSrcBuffer+nOffset) < 100 )
// 					{
// 						xRGB = m_pImage->GetPixelColor(nX+j,nHeight - nY - i);
// 						
// //						xRGB.rgbRed ^= 255;
// //						xRGB.rgbGreen ^= 255;
// //						xRGB.rgbBlue ^= 255;
// 						GetXORValue(xRGB.rgbRed); 
// 						GetXORValue(xRGB.rgbGreen); 
// 						GetXORValue(xRGB.rgbBlue); 
// 						
// 						m_pImage->SetPixelColor(nX+j,nHeight - nY - i,xRGB);
// 
// 						if( bSetOrgImage )
// 						{
// 							xRGB = m_pOrgImage->GetPixelColor(nX+j,nHeight - nY - i);
// 							GetXORValue(xRGB.rgbRed); 
// 							GetXORValue(xRGB.rgbGreen); 
// 							GetXORValue(xRGB.rgbBlue);
// 							m_pOrgImage->SetPixelColor(nX+j,nHeight - nY - i,xRGB);
// 						}	
// 					}	
// 				}
// 			}
// 		}
// 		break;
// 	case 16:
// 		{
// 		}
// 		break;
// 	case 24:
// 	case 32:
// 		{
// 			int nHeight = m_pImage->GetHeight();
// 
// 			RGBQUAD xRGB;
// 			int nOffset = 0;
// 			int nPixel = stBitMap.bmBitsPixel >> 3;
// 			for(int i=0;i<stBitMap.bmHeight;i++)
// 			{
// 				for(int j=0;j<stBitMap.bmWidth;j++)
// 				{
// 					nOffset = (i*stBitMap.bmWidth +j)*nPixel;
// 					
// 					if( *(pSrcBuffer+nOffset) < 100 )
// 					{
// 						xRGB = m_pImage->GetPixelColor(nX+j,nHeight - nY - i);
// 						
// 						GetXORValue(xRGB.rgbRed); 
// 						GetXORValue(xRGB.rgbGreen); 
// 						GetXORValue(xRGB.rgbBlue);
// 						
// 						m_pImage->SetPixelColor(nX+j,nHeight - nY - i,xRGB);
// 
// 						if( bSetOrgImage )
// 						{
// 							xRGB = m_pOrgImage->GetPixelColor(nX+j,nHeight - nY - i);
// 							GetXORValue(xRGB.rgbRed); 
// 							GetXORValue(xRGB.rgbGreen); 
// 							GetXORValue(xRGB.rgbBlue);
// 							m_pOrgImage->SetPixelColor(nX+j,nHeight - nY - i,xRGB);
// 						}
// 					}	
// 				}
// 			}
// 		}
// 		break;
// 	default:
// 		break;
// 	}
// 
// 	MySafeDeleteMAB(pSrcBuffer);

	return DD_ERR_SUCCESS;
}



int xkImgBit8::GetRetInfo(void **ppVoid)
{
	*ppVoid = (void*)m_pImage;

	return 1;
}


int xkImgBit8::ConpositeImageTo(void *pImage,RECT *pRect)
{
	CxImage *pAreaImage = (CxImage*)pImage;
	if( NULL == pAreaImage     ||
		!pAreaImage->IsValid() ||
		!m_pImage->IsValid() )
	{
		return DD_ERR_FAILURE;
	}

	int nLeft = 0,nTop = 0;
	if( NULL != pRect )
	{
		nLeft = pRect->left;
		nTop  = pRect->top;
	}

	int nW  = pAreaImage->GetWidth();
	int nH = pAreaImage->GetHeight();
	int nWidth = m_pImage->GetWidth();
	int nHeight = m_pImage->GetHeight();

	nW = min(nW, nWidth - nLeft);
	nH = min(nH, nHeight - nTop);

	RGBQUAD xRGB; 

	for(int i=0;i<nH;i++)
	{
		for(int j=0;j<nW;j++)
		{
            xRGB = pAreaImage->GetPixelColor(j,nH-i);
            m_pImage->SetPixelColor(nLeft+j,nHeight-nTop-i,xRGB);
		}
	}

	return DD_ERR_SUCCESS;
}